﻿namespace Pyramid.IO
{
    using System;

    public abstract class Stream
        : IDisposable
    {
        //TODO: Implement these
        //public virtual IAsyncResult BeginRead(Tryte[] buffer, int offset, int count, AsyncCallback callback, object state);
        //public virtual IAsyncResult BeginWrite(Tryte[] buffer, int offset, int count, AsyncCallback callback, object state);

        public abstract bool CanRead { get; }

        public abstract bool CanSeek { get; }

        public abstract bool CanWrite { get; }

        public abstract void Flush();

        public abstract long Length
        {
            get;
        }

        public abstract long Position
        {
            get;
            set;
        }

        public abstract int Read(Tryte[] buffer, int offset, int count);

        public virtual Int27 ReadTryte()
        {
            Tryte[] buffer = new Tryte[1];

            if (this.Read(buffer, 0, 1) == 0)
            {
                return Int27.MinValue;
            }
            else
            {
                return buffer[0];
            }
        }

        public abstract long Seek(long offset, System.IO.SeekOrigin origin);

        public abstract void SetLength(long value);

        public abstract void Write(Tryte[] buffer, int offset, int count);

        public virtual void WriteTryte(Tryte value)
        {
            this.Write(new[] { value }, 0, 1);
        }

        public void Dispose()
        {
            Dispose(true);
        }

        protected virtual void Dispose(bool isDisposing)
        {
        }
    }
}
